package cn.nawang.ebeim.api.utils;

import java.io.IOException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.jasypt.encryption.pbe.StandardPBEByteEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;

import cn.nawang.ebeim.api.exception.EncryptException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * @ClassName: DesUtil
 * @Description: TODO
 * @author fanyb
 * @date Aug 26, 2015 10:45:17 AM
 * @version v1.0
 */
public class DesUtil {
  private final static String DES = "DES";
  private final static String DES2="DES/ECB/PKCS5Padding";
  private StandardPBEByteEncryptor binaryEncryptor = null;

  public void init(String password) {
    EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
    config.setAlgorithm("PBEWITHSHA1ANDDESEDE");
    config.setPassword(password);
    binaryEncryptor = new StandardPBEByteEncryptor();
    binaryEncryptor.setConfig(config);
  }

  public static void main(String[] args) throws Exception {
    String data =
        "{'startTime' : '2000','expiryTime' : '2001','licenseID' : '123456','licensePassword' : '','terminalID' : '123456','customName' : '厦门纳网','customID' : '7889'}";
    String key = "nawangdes";
    System.err.println(encrypt(data, key));
    System.err.println(decrypt(encrypt(data, key), key));

  }

  /**
   * Description 根据键值进行加密
   * 
   * @param data
   * @param key 加密键byte数组
   * @return
   * @throws Exception
   */
  public static String encrypt(String data, String key) throws Exception {
    byte[] bt = encrypt(data.getBytes(), key.getBytes());
    String strs = new BASE64Encoder().encode(bt);
    return strs;
  }

  /**
   * Description 根据键值进行解密
   * 
   * @param data
   * @param key 加密键byte数组
   * @return
   * @throws IOException
   * @throws Exception
   */
  public static String decrypt(String data, String key) throws IOException, Exception {
    if (data == null) return null;
    BASE64Decoder decoder = new BASE64Decoder();
    byte[] buf = decoder.decodeBuffer(data);
    byte[] bt = decrypt(buf, key.getBytes());
    return new String(bt);
  }

  /**
   * Description 根据键值进行加密
   * 
   * @param data
   * @param key 加密键byte数组
   * @return
   * @throws Exception
   */
  private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
    // 生成一个可信任的随机数源
    SecureRandom sr = new SecureRandom();

    // 从原始密钥数据创建DESKeySpec对象
    DESKeySpec dks = new DESKeySpec(key);

    // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
    SecretKey securekey = keyFactory.generateSecret(dks);

    // Cipher对象实际完成加密操作
    Cipher cipher = Cipher.getInstance(DES2);

    // 用密钥初始化Cipher对象
    cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

    return cipher.doFinal(data);
  }


  /**
   * Description 根据键值进行解密
   * 
   * @param data
   * @param key 加密键byte数组
   * @return
   * @throws Exception
   */
  private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
    // 生成一个可信任的随机数源
    SecureRandom sr = new SecureRandom();

    // 从原始密钥数据创建DESKeySpec对象
    DESKeySpec dks = new DESKeySpec(key);

    // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
    SecretKey securekey = keyFactory.generateSecret(dks);

    // Cipher对象实际完成解密操作
    Cipher cipher = Cipher.getInstance(DES2);

    // 用密钥初始化Cipher对象
    cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

    return cipher.doFinal(data);
  }

  public byte[] desEncrypt(byte[] buff) throws EncryptException {
    try {
      return binaryEncryptor.encrypt(buff);
    } catch (Throwable e) {
      throw new EncryptException("加密失败：" + e.getMessage(), e);
    }

  }

  public byte[] desDecrypt(byte[] buff) throws EncryptException {

    try {
      return binaryEncryptor.decrypt(buff);
    } catch (Throwable e) {
      throw new EncryptException("解密失败：" + e.getMessage(), e);
    }
  }
}
